//
// DotNetNuke - http://www.dotnetnuke.com
// Copyright (c) 2002-2010
// by Perpetual Motion Interactive Systems Inc. ( http://www.perpetualmotion.ca )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.XPath;
using DotNetNuke.Common;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Entities.Host;
using DotNetNuke.Services.Cache;
namespace DotNetNuke.HttpModules.RequestFilter
{
	[Serializable(), XmlRoot("RewriterConfig")]
	public class RequestFilterSettings
	{
		private const string c_RequestFilterConfig = "RequestFilter.Config";
		private bool _Enabled;
		public bool Enabled {
			get { return Host.EnableRequestFilters; }
		}
		private List<RequestFilterRule> _Rules = new List<RequestFilterRule>();
		public List<RequestFilterRule> Rules {
			get { return _Rules; }
			set { _Rules = value; }
		}
		public static RequestFilterSettings GetSettings()
		{
			RequestFilterSettings _Settings = (RequestFilterSettings)DataCache.GetCache(c_RequestFilterConfig);
			if (_Settings == null) {
				_Settings = new RequestFilterSettings();
				string filePath = DotNetNuke.Common.Utilities.Config.GetPathToFile(ConfigFileType.DotNetNuke);
				FileStream fileReader = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
				XPathDocument doc = new XPathDocument(fileReader);
				XPathNodeIterator ruleList = doc.CreateNavigator().Select("/configuration/blockrequests/rule");
				while (ruleList.MoveNext()) {
					try {
						string serverVar = ruleList.Current.GetAttribute("servervar", string.Empty);
						string values = ruleList.Current.GetAttribute("values", string.Empty);
						RequestFilterRuleType ac = (RequestFilterRuleType)Enum.Parse(typeof(RequestFilterRuleType), ruleList.Current.GetAttribute("action", string.Empty));
						RequestFilterOperatorType op = (RequestFilterOperatorType)Enum.Parse(typeof(RequestFilterOperatorType), ruleList.Current.GetAttribute("operator", string.Empty));
						string location = ruleList.Current.GetAttribute("location", string.Empty);
						RequestFilterRule rule = new RequestFilterRule(serverVar, values, op, ac, location);
						_Settings.Rules.Add(rule);
					} catch (Exception ex) {
						DotNetNuke.Services.Exceptions.Exceptions.LogException(new Exception(string.Format("Unable to read RequestFilter Rule: {0}:", ruleList.Current.OuterXml), ex));
					}
				}
				if ((File.Exists(filePath))) {
					DataCache.SetCache(c_RequestFilterConfig, _Settings, new DNNCacheDependency(filePath));
				}
			}
			return _Settings;
		}
		public static void Save(List<RequestFilterRule> rules)
		{
			string filePath = DotNetNuke.Common.Utilities.Config.GetPathToFile(ConfigFileType.DotNetNuke);

			XmlDocument doc = new XmlDocument();
			doc.Load(filePath);
			XmlNode ruleRoot = doc.SelectSingleNode("/configuration/blockrequests");
			ruleRoot.RemoveAll();
			foreach (RequestFilterRule rule in rules) {
				XmlElement xmlRule = doc.CreateElement("rule");
				XmlAttribute var = doc.CreateAttribute("servervar");
				var.Value = rule.ServerVariable;
				xmlRule.Attributes.Append(var);
				XmlAttribute val = doc.CreateAttribute("values");
				val.Value = rule.RawValue;
				xmlRule.Attributes.Append(val);
				XmlAttribute op = doc.CreateAttribute("operator");
				op.Value = rule.Operator.ToString();
				xmlRule.Attributes.Append(op);
				XmlAttribute action = doc.CreateAttribute("action");
				action.Value = rule.Action.ToString();
				xmlRule.Attributes.Append(action);
				XmlAttribute location = doc.CreateAttribute("location");
				location.Value = rule.Location;
				xmlRule.Attributes.Append(location);
				ruleRoot.AppendChild(xmlRule);
			}
			XmlWriterSettings settings = new XmlWriterSettings();
			settings.Indent = true;
			using (XmlWriter writer = XmlWriter.Create(filePath, settings)) {
				doc.WriteContentTo(writer);
			}
		}
	}
}
